﻿/* Nibiru Studio Engine Version [1062] */
#include "EyeManager.h"
#include "Platform/Android/JNI/NAndroidJavaClass.h"
using namespace std;


ENGINE_NAMESPACE_BEGIN

IMPLEMENT_RTTI_NoParent(EyeManager)

EyeManager* EyeManager::instance()
{
    static EyeManager instnce;
    return &instnce;
}

EyeManager::EyeManager()
{
    NAndroidJavaClassPtr clazzTracker = NAndroidJavaClass::MakeSharedPtr("com/nsproject/client/TrackerApi");
    m_trackerApi = NAndroidJavaObject::MakeSharedPtr(clazzTracker);
    //
    m_trackerApi->CallVoidMethod("initial", "(Landroid/content/Context;)V", NApplication::GetAndroidActivity());
    NDebug::Log("7Inv trackerApi initial success");
}

ServiceResult EyeManager::start()
{
    int code = m_trackerApi->CallIntMethod("start", "()I");
    if (code != 0)
    {
        string msg = getErrorMsg();
        ServiceResult serviceResult = ServiceResult::failure(code, msg);
        NDebug::Log("%s start error, %s", EYE_TAG, serviceResult.toString().c_str());
        return serviceResult;
    }
    NDebug::Log("%s start success", EYE_TAG);
    return ServiceResult::success("start success");
}

ServiceResult EyeManager::stop()
{
    int code = m_trackerApi->CallIntMethod("release", "()I");
    if (code != 0)
    {
        string msg = getErrorMsg();
        ServiceResult serviceResult = ServiceResult::failure(code, msg);
        NDebug::Log("%s stop error, %s", EYE_TAG, serviceResult.toString().c_str());
        return serviceResult;
    }
    return ServiceResult::success("stop success");
}

ServiceResult EyeManager::getEyeData(EyeDataBasic& eyedDataBasic)
{
    string eyeDataStr = m_trackerApi->CallStringMethod("getEyeData", "()Ljava/lang/String;");
    if (eyeDataStr == "-1")
    {
        string msg = getErrorMsg();
        ServiceResult serviceResult = ServiceResult::failure(-1, msg);
        NDebug::Log("%s getEyeData error, %s", EYE_TAG, serviceResult.toString().c_str());
        return serviceResult;
    }
    else if (eyeDataStr == "")
    {
        return ServiceResult::failure(-1, "getEyeData null");
    }
    stringToEyeDataBasic(eyeDataStr, eyedDataBasic);
    return ServiceResult::success("getEyeData success");
}

ServiceResult EyeManager::startCalibration(float minX, float maxX,
    float minY, float maxY, int calibCount)
{
    NDebug::Log("%s startCalibration x=%f, y=%f, calibCount=%d", EYE_TAG, maxX, maxY, calibCount);
    int code = m_trackerApi->CallIntMethod("startCalibration", "(FFFFI)I", minX, maxX,
        minY, maxY, calibCount);
    if (code != 0)
    {
        string msg = getErrorMsg();
        ServiceResult serviceResult = ServiceResult::failure(code, msg);
        NDebug::Log("%s startCalibration error, %s", EYE_TAG, serviceResult.toString().c_str());
        return serviceResult;
    }
    return ServiceResult::success("startCalibration success");
}

ServiceResult EyeManager::startCalibrationPoint(int index, float leftX, float leftY,
    float rightX, float rightY)
{
    int code = m_trackerApi->CallIntMethod("startCalibrationPoint", "(IFFFF)I",
        index, leftX, leftY, rightX, rightY);
    if (code != 0)
    {
        string msg = getErrorMsg();
        ServiceResult serviceResult = ServiceResult::failure(code, msg);
        NDebug::Log("%s startCalibrationPoint error, %s", EYE_TAG, serviceResult.toString().c_str());
        return serviceResult;
    }
    return ServiceResult::success("startCalibrationPoint success");
}

ServiceResult EyeManager::cancelCalibrationPoint()
{
    int code = m_trackerApi->CallIntMethod("cancelCalibrationPoint", "()I");
    if (code != 0)
    {
        string msg = getErrorMsg();
        ServiceResult serviceResult = ServiceResult::failure(code, msg);
        NDebug::Log("%s cancelCalibrationPoint error, %s", EYE_TAG, serviceResult.toString().c_str());
        return serviceResult;
    }
    return ServiceResult::success("cancelCalibrationPoint success");
}

ServiceResult EyeManager::completeCalibration()
{
    int code = m_trackerApi->CallIntMethod("completeCalibration", "()I");
    if (code != 0)
    {
        string msg = getErrorMsg();
        ServiceResult serviceResult = ServiceResult::failure(code, msg);
        NDebug::Log("%s completeCalibration error, %s", EYE_TAG, serviceResult.toString().c_str());
        return serviceResult;
    }
    return ServiceResult::success("completeCalibration success");
}

int EyeManager::getCalibPercent()
{
    return m_trackerApi->CallIntMethod("getCalibPercent", "()I");
}

int EyeManager::getCalibFinishCode()
{
    return m_trackerApi->CallIntMethod("getCalibFinishCode", "()I");
}

ServiceResult EyeManager::saveImage(const string& imageName)
{
    jstring jName = m_trackerApi->StringToJString(imageName);
    int code = m_trackerApi->CallIntMethod("saveImage", "(Ljava/lang/String;)I",
        jName);
    if (code != 0)
    {
        string msg = getErrorMsg();
        ServiceResult serviceResult = ServiceResult::failure(code, msg);
        NDebug::Log("%s saveImage error, %s", EYE_TAG, serviceResult.toString().c_str());
        return serviceResult;
    }
    return ServiceResult::success("saveImage success");
}

ServiceResult EyeManager::registerImageCallback()
{
    int code = m_trackerApi->CallIntMethod("registerImageCallback", "()I");
    if (code != 0)
    {
        string msg = getErrorMsg();
        ServiceResult serviceResult = ServiceResult::failure(code, msg);
        NDebug::Log("%s registerImageCallback error, %s", EYE_TAG, serviceResult.toString().c_str());
        return serviceResult;
    }
    return ServiceResult::success("registerImageCallback success");
}

ServiceResult EyeManager::unregisterImageCallback()
{
    int code = m_trackerApi->CallIntMethod("unregisterImageCallback", "()I");
    if (code != 0)
    {
        string msg = getErrorMsg();
        ServiceResult serviceResult = ServiceResult::failure(code, msg);
        NDebug::Log("%s unregisterImageCallback error, %s", EYE_TAG, serviceResult.toString().c_str());
        return serviceResult;
    }
    return ServiceResult::success("unregisterImageCallback success");
}

string EyeManager::getErrorMsg()
{
    string msg = m_trackerApi->CallStringMethod("getErrorMessage", "()Ljava/lang/String;");
    return msg;
}

// 7In gaze#valid#-1.0#-1.0#-1.0#leftPupil#valid#-1.0#-1.0#rightPupil#valid#-1.0#-1.0
//      0    1     2    3    4    5         6     7    8    9          10    11   12
void EyeManager::stringToEyeDataBasic(const string& eyeDataStr, EyeDataBasic& eyeDataBasic)
{
    std::string delimiter = "#";
    std::istringstream iss(eyeDataStr);
    std::vector<string> result;
    std::string item;
    while (std::getline(iss, item, delimiter[0]))
    {
        result.push_back(item);
    }

    eyeDataBasic.gazeValid = stof(result[1]);
    eyeDataBasic.gazeX = stof(result[2]);
    eyeDataBasic.gazeY = stof(result[3]);
    eyeDataBasic.gazeZ = stof(result[4]);

    eyeDataBasic.leftPupilValid = stof(result[6]);
    eyeDataBasic.leftPupilX = stof(result[7]);
    eyeDataBasic.leftPupilY = stof(result[8]);

    eyeDataBasic.rightPupilValid = stof(result[10]);
    eyeDataBasic.rightPupilX = stof(result[11]);
    eyeDataBasic.rightPupilY = stof(result[12]);
}



ENGINE_NAMESPACE_END


